#include "SpriteFixer.h"


ILenum SpriteFixer::_detectType( std::string str )
{
	char f=str[0], s=str[1], t=str[2];
	switch(f)
	{
	case 'P':
	case 'p':
		return IL_PNG;
	case 'B':
	case 'b':
		return IL_BMP;
	case 'j':
	case 'J':
		return IL_JPG;
	default:
		return 0;
	}
}

SpriteFixer::SpriteFixer( void ) : mData(0)
{

}

SpriteFixer::~SpriteFixer( void )
{

}

void SpriteFixer::Init( int textureSizeX, int textureSizeY, int numRows, int numColumns )
{
	if(mData)
	{
		free(mData);
	}
	else
	{
		ilInit();
		iluInit();
		ilutInit();
		ilutRenderer(ILUT_OPENGL);
	}
	mTextureSizeX = textureSizeX;
	mTextureSizeY = textureSizeY;
	mNumRows = numRows;
	mNumColumns = numColumns;
	mData = (unsigned char*)malloc(mTextureSizeX*mTextureSizeY*mNumRows*mNumColumns*4);
}

void SpriteFixer::AddTexture( int row, int column, std::string path, int xOffset/*=0*/, int yOffset/*=0*/, int xSize/*=-1*/, int ySize/*=-1*/, bool makeBackgroundTransparent/*=true*/, int backgroundPixelX/*=0*/, int backgroundPixelY/*=0*/ )
{
	int xDataOffset = row * mTextureSizeX;
	int yDataOffset = column * mTextureSizeY;
	int pixelPerColumn = mNumRows * mTextureSizeX;

	FILE *f = fopen(path.c_str(), "rb");
	fseek(f, 0, SEEK_END);
	unsigned int sz = ftell(f);
	unsigned char *data=(unsigned char*)malloc(sz*sizeof(unsigned char));
	fseek(f, 0, SEEK_SET);
	fread(data, 1, sz,f);
	fclose(f);

	unsigned int temp;
	ilGenImages(1, &temp);
	ilBindImage(temp);
	ILenum type = _detectType(path.substr(1+path.find_last_of('.')));
	ilLoadL(type, data, sz);
	ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
	free(data);
	// pixel info is in data!
	data = ilGetData();
	sz =ilGetInteger(IL_IMAGE_WIDTH) * ilGetInteger(IL_IMAGE_HEIGHT)*4;
	int texwidth = ilGetInteger(IL_IMAGE_WIDTH);
	int texheight = ilGetInteger(IL_IMAGE_HEIGHT);
	if(xSize == -1)
		xSize = texwidth;
	if(ySize == -1)
		ySize = texheight;
	if(makeBackgroundTransparent)
	{
		char r,g,b;
		r = data[backgroundPixelX*4+backgroundPixelY*4*texwidth];
		g = data[backgroundPixelX*4+backgroundPixelY*4*texwidth+1];
		b = data[backgroundPixelX*4+backgroundPixelY*4*texwidth+2];
		int pixelcnt = texwidth*texheight*4;
		for(int i=0; i<pixelcnt; i+=4)
		{
			if(r == data[i] && g == data[i+1] && b == data[i+2])
			{
				data[i+3]=0;
			}
		}
	}

	for(int curColumn=0; curColumn<ySize; curColumn++)
	{
		// 			printf("Left: mData + xRowOffset(%d*4) + yOffsetBytes(%d*%d*4 = %d) + currentColumnOffset(%d*%d*4 = %d) = %d!\n", 
		// 				xDataOffset,
		// 				pixelPerColumn, yDataOffset, pixelPerColumn*yDataOffset*4, pixelPerColumn, curColumn, pixelPerColumn*curColumn*4,
		// 				pixelPerColumn*yDataOffset*4 + pixelPerColumn*curColumn*4);
		// 			printf("Right: data + xOffsetBytes(%d*4) + yOffsetBytes(%d*%d*4 = %d) + currentColumnOffset(%d*%d*4 = %d) = %d!\n",
		// 				xOffset, yOffset, texwidth, yOffset*texwidth*4, curColumn, texwidth, curColumn*texwidth*4,
		// 				xOffset*4+yOffset*texwidth*4 + curColumn*texwidth*4);
		memcpy(mData + xDataOffset*4+ pixelPerColumn*yDataOffset*4 + pixelPerColumn*curColumn*4, data+xOffset*4+yOffset*texwidth*4 + curColumn*texwidth*4, xSize*4);
		//			getchar();
	}
	ilDeleteImages(1, &temp);
}

void SpriteFixer::SaveTexture( std::string path )
{
	ILenum type = _detectType(path.substr(1+path.find_last_of('.')));
	unsigned int temp;
	ilGenImages(1, &temp);
	ilTexImage(mNumRows*mTextureSizeX, mNumColumns*mTextureSizeY, 0, 4, IL_RGBA, IL_UNSIGNED_BYTE, mData);
	ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);

	ilEnable(IL_FILE_OVERWRITE);
	ILboolean bl =ilSave(type, path.c_str());
	if(bl)
	{
		ILenum err = ilGetError();
		printf("ERROR: %s", iluErrorString(err));
		printf("\n");
	}
}